package com.example.communitypro.websocket;

import com.alibaba.fastjson.JSONObject;

import com.example.communitypro.config.WebSocketConfig;
import com.example.communitypro.mapper.UserInformationMapper;
import com.example.communitypro.pojo.Message;
import com.example.communitypro.pojo.UserInformation;
import com.example.communitypro.service.ChatService;
import com.example.communitypro.util.SpringUtil;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.models.auth.In;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint(value = "/websocket/{userName}", configurator = WebSocketConfig.class)
@Component
public class MyWebSocket {

    //用来存放每个客户端对应的MyWebSocket对象。
    private static final CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
    //用来记录username和该session进行绑定
    private static final Map<Integer, Session> map = new HashMap<Integer, Session>();
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
    //用户名
    private Integer username;
    //获取全局容器
    private ApplicationContext applicationContext;
    //聊天逻辑层service
    private ChatService chatService;
    //用户Dao管理
    private UserInformationMapper userInformationMapper;


    /**
     * 连接建立成功调用的方法，初始化昵称、session
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userName") Integer userName) {

        //获取登录时存放httpSession的用户数据
        try {
            ApplicationContext applicationContext = SpringUtil.getApplicationContext();
            this.userInformationMapper = (UserInformationMapper) applicationContext.getBean("userInformationMapper");
            UserInformation userinformation = userInformationMapper.selectByPrimaryKey(userName);
            this.applicationContext = applicationContext;
            this.session = session;
            this.username = userinformation.getUserNo();
            this.chatService = (ChatService) applicationContext.getBean("chatServiceImpl");
            map.put(username, session);
            userInformationMapper.setStatus(userName, 1);
            webSocketSet.add(this);     //加入set中
            System.out.println(username + " is open connect");
            System.out.println("Online users:" + map.keySet());
            System.out.println(map);
        }catch (Exception e){
            e.printStackTrace();
            return;
        }

    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userName") Integer userName) {
        //断开连接，重置窗口值
        System.out.println(userName + " is close connect");
        userInformationMapper.setStatus(userName, 0);
        webSocketSet.remove(this);  //从set中删除
        map.remove(userName);
        System.out.println("Online users:" + map.keySet());

    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
        ObjectMapper objectMapper = new ObjectMapper();
        Message chatMsg;
        try {
            chatMsg = objectMapper.readValue(message, Message.class);
            //对chatMsg进行装箱
            chatMsg.setSender(username);
            java.util.Date javaDate = new java.util.Date();
            long time = javaDate.getTime();
            Timestamp stamp = new Timestamp(time);
            chatMsg.setSendTime(stamp);
            chatMsg.setIsRead(0);
            Session fromSession = map.get(chatMsg.getSender());
            Session toSession = map.get(chatMsg.getReceiver());
            int id = chatService.isFirstChat(chatMsg.getSender(), chatMsg.getReceiver());
            if (id != -1) {
                chatMsg.setListId(id);
            }
            chatService.saveMessage(chatMsg);
            System.out.println(chatMsg);
            //发送给接收者.
            fromSession.getAsyncRemote().sendText(JSONObject.toJSONString(chatMsg));
            if(toSession!=null)
                //发送给发送者.
                toSession.getAsyncRemote().sendText(JSONObject.toJSONString(chatMsg));
//            判断两者是否第一次聊天，进行关系表、聊天列表、空白信息的初始化

//            //保存聊天记录信息
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error, @PathParam("userName") Integer userName) {
        error.printStackTrace();
        webSocketSet.remove(this);
        userInformationMapper.setStatus(userName, 0);
        map.remove(userName);
        System.out.println("Online users:" + map.keySet());
    }

    /**
     * 群发自定义消息
     */
    public void broadcast(String message) {
        for (MyWebSocket item : webSocketSet) {

            //异步发送消息.
            item.session.getAsyncRemote().sendText(message);
        }
    }
}
